package com.atguigu.gmall.payment.service.impl;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.PaymentStatus;
import com.atguigu.gmall.model.enums.PaymentType;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.payment.PaymentInfo;
import com.atguigu.gmall.order.client.OrderFeignClient;
import com.atguigu.gmall.payment.config.AlipayConfig;
import com.atguigu.gmall.payment.mapper.PaymentInfoMapper;
import com.atguigu.gmall.payment.service.AlipayService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.filter.OrderedFilter;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 支付宝管理
 * 统一收单下单并支付页面接口
 */
@Service
@Slf4j
public class AlipayServiceImpl implements AlipayService {


    @Autowired
    private OrderFeignClient orderFeignClient;
    @Autowired
    private PaymentInfoMapper paymentInfoMapper;
    @Autowired
    private AlipayClient alipayClient;


    //统一收单下单并支付页面接口
    @Override
    public String createPage(Long orderId) {

        //1: 保存本次交易 （支付信息表）
        //先查询订单
        OrderInfo orderInfo = orderFeignClient.getOrderInfoById(orderId);
        //判断订单状态是未支付状态
        if(OrderStatus.UNPAID.name().equals(orderInfo.getOrderStatus())){
            //先查询支付信息表 确认是否存在
            PaymentInfo paymentInfo = paymentInfoMapper.
                    selectOne(new QueryWrapper<PaymentInfo>().eq("order_id", orderId));
            if (null == paymentInfo) {
                //保存支付信息表
                paymentInfo = new PaymentInfo();
                //主键
                //对外业务编号
                paymentInfo.setOutTradeNo(orderInfo.getOutTradeNo());
                //订单编号
                paymentInfo.setOrderId(orderInfo.getId());
                //支付宝
                paymentInfo.setPaymentType(PaymentType.ALIPAY.name());
                //支付金额
                paymentInfo.setTotalAmount(orderInfo.getTotalAmount());
                //交易内容
                paymentInfo.setSubject(orderInfo.getTradeBody());
                //创建时间
                paymentInfo.setCreateTime(new Date());
                //支付状态
                paymentInfo.setPaymentStatus(PaymentStatus.UNPAID.name());

                //保存支付信息表
                paymentInfoMapper.insert(paymentInfo);

            }
            //2:调用支付宝接口
            AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
            Map map = new HashMap<>();
            //外对订单编号
            map.put("out_trade_no", orderInfo.getOutTradeNo());
            //销售产品码
            map.put("product_code", "FAST_INSTANT_TRADE_PAY");
            //总金额
            //map.put("total_amount",orderInfo.getTotalAmount());
            map.put("total_amount", "0.01");
            //订单标题
            map.put("subject", orderInfo.getTradeBody());
            //设置请求参数
            request.setBizContent(JSON.toJSONString(map));
            //支付成功了  跳转到商户的成功页面   同步
            request.setReturnUrl(AlipayConfig.return_payment_url);
            //支付成功了 异步通知回调路径
            request.setNotifyUrl(AlipayConfig.notify_payment_url);
            AlipayTradePagePayResponse response = null;
            try {
                //执行调用
                response = alipayClient.pageExecute(request);

            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
            if (response.isSuccess()) {
                System.out.println("调用成功");
                return response.getBody();
            } else {
                System.out.println("调用失败");
                return null;
            }
        }else{
            //判断 已支付  关闭
            return null;
        }

    }

    @Autowired
    private RabbitService rabbitService;

    //支付宝异步回调方法 更新支付信息相关数据
    @Override
    public void paySuccess(Map<String, String> paramsMap) {
        //1:查询支付信息
        String out_trade_no = paramsMap.get("out_trade_no");//交易号
        PaymentInfo paymentInfo = paymentInfoMapper.selectOne(new QueryWrapper<PaymentInfo>().eq("out_trade_no", out_trade_no));
        //判断是否存在此交易
        if (null != paymentInfo) {
            //2：判断是否未更新  未支付状态     如果已经支付或已经关闭 都不进行更新
            if (paymentInfo.getPaymentStatus().equals(PaymentStatus.UNPAID.name())) {
                //更新支付信息
                paymentInfo.setPaymentStatus(PaymentStatus.PAID.name());
                //更新交易号
                paymentInfo.setTradeNo(paramsMap.get("trade_no"));
                //更新回调时间
                paymentInfo.setCallbackTime(new Date());
                //更新回调信息
                paymentInfo.setCallbackContent(JSON.toJSONString(paramsMap));
                paymentInfoMapper.updateById(paymentInfo);

                //上面更新了支付信息
                //发消息给订单 更新订单
                //更新订单表状态
                rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_PAYMENT_PAY,
                        MqConst.ROUTING_PAYMENT_PAY, paymentInfo.getOrderId().toString());

            }
        } else {
            //记录日志
            log.info("此交易不存在：" + JSON.toJSONString(paramsMap));
        }
    }

    //退款
    @Override
    public String refund(String out_trade_no) {
        //1:查询支付信息表
        PaymentInfo paymentInfo = paymentInfoMapper.selectOne(new QueryWrapper<PaymentInfo>().eq("out_trade_no", out_trade_no));
        //2:退款
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        Map map = new HashMap();
        map.put("refund_amount", "0.01");
        map.put("out_trade_no", out_trade_no);
        //map.put("trade_no",paymentInfo.getTradeNo());
        request.setBizContent(JSON.toJSONString(map));
        AlipayTradeRefundResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        if (response.isSuccess()) {
            System.out.println("调用成功");
            //更新支付信息表 更新状态
        } else {
            System.out.println("调用失败");
        }
        return null;
    }

    //更新支付信息的关闭状态  同时关闭支付宝
    @Override
    public void closePaymentInfo(String orderId) {

        //1:更新支付信息 前题  状态是未支付
        PaymentInfo paymentInfo = paymentInfoMapper
                .selectOne(new QueryWrapper<PaymentInfo>().eq("order_id", orderId));
        if(null != paymentInfo){
            //状态
            if(paymentInfo.getPaymentStatus().equals(PaymentStatus.UNPAID.name())){
                paymentInfo.setPaymentStatus(PaymentStatus.ClOSED.name());
                //更新支付信息表
                paymentInfoMapper.updateById(paymentInfo);
                //关闭交易
                if(PaymentType.ALIPAY.name().equals(paymentInfo.getPaymentType())){
                    //关闭支付宝
                    closeAlipay(paymentInfo.getOutTradeNo());
                }
            }
        }else{
            log.info("无此支付信息");
        }

    }
    //关闭支付宝
    private void closeAlipay(String outTradeNo) {
        AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
        Map map = new HashMap();
        map.put("out_trade_no",outTradeNo);
        request.setBizContent(JSON.toJSONString(map));
        AlipayTradeCloseResponse response = null;
        try {
            response = alipayClient.execute(request);
            if(response.isSuccess()){
                System.out.println("调用成功");
            } else {
                System.out.println("调用失败");
            }
        } catch (Exception e) {
           // e.printStackTrace();
            log.info("出异常了：" + e.getMessage());
        }

    }


}
